package lg.minecraft.plugin.pokemonmenu.util;

import com.cobblemon.mod.common.pokemon.Pokemon;
import lg.minecraft.plugin.cobblemoncore.util.BukkitNmsConverter;
import lg.minecraft.plugin.pokemonmenu.manager.PokemonDataManager;
import lombok.Getter;
import lombok.SneakyThrows;
import net.minecraft.*;
import org.bukkit.inventory.ItemStack;

import java.util.Optional;
import java.util.UUID;

/**
 * 宝可梦物品NBT处理工具类
 * 提供从物品中读取宝可梦数据和向物品中写入宝可梦数据的功能
 * 
 * @author langle__
 * @version 1.0
 */
public class PokemonNBTUtil {

    /**
     * 将宝可梦数据写入物品NBT
     *
     * @param pokemon 宝可梦实体
     * @param itemStack 物品堆
     */
    public static void writePokemonToNBT(Pokemon pokemon, class_1799 itemStack) {
        class_2487 nbt = new class_2487();

        UUID uuid = UUID.randomUUID();
        nbt.method_10582("pokemon_cloud", uuid.toString());
        PokemonDataManager.INSTANCE.savePokemon(uuid, pokemon);

        itemStack.method_57379(class_9334.field_49628, class_9279.method_57456(nbt));
    }

    /**
     * 从物品中提取宝可梦NBT数据
     *
     * @param bukkitItem 物品堆
     * @param registryAccess 注册表访问器
     * @return 宝可梦实体和清理任务的包装对象
     */
    public static Entry extractPokemonFromNBT(ItemStack bukkitItem, class_5455 registryAccess) {
        class_1799 item = BukkitNmsConverter.toItemStack(bukkitItem);
        class_9279 class9279 = item.method_57353().method_57829(class_9334.field_49628);
        if (class9279 == null) return new Entry(null);

        Optional<class_9279> customData = Optional.of(class9279);
        class_2487 nbt = customData.get().method_57461();

        return extractPokemonFromNBT(nbt, registryAccess);
    }

    /**
     * 从NBT中提取宝可梦数据
     *
     * @param nbt NBT数据
     * @param registryAccess 注册表访问器
     * @return 宝可梦实体和清理任务的包装对象
     */
    @SneakyThrows
    public static Entry extractPokemonFromNBT(class_2487 nbt, class_5455 registryAccess) {
        Pokemon pokemon = null;
        Runnable runnable = null;

        if (nbt.method_10545("pokemon_cloud")) {
            String uuidString = nbt.method_10558("pokemon_cloud");
            UUID uuid = UUID.fromString(uuidString);
            pokemon = PokemonDataManager.INSTANCE.getPokemon(uuid);
            runnable = () -> PokemonDataManager.INSTANCE.removePokemon(uuid);
        }

        return new Entry(pokemon, runnable);
    }

    public static class Entry {

        @Getter
        private final Pokemon pokemon;
        private final Runnable runnable;

        public Entry(Pokemon pokemon) {
            this.pokemon = pokemon;
            this.runnable = null;
        }

        public Entry(Pokemon pokemon, Runnable runnable) {
            this.pokemon = pokemon;
            this.runnable = runnable;
        }

        public void run() {
            if (runnable == null) return;
            runnable.run();
        }

    }

}
